package demo

import (
	"context"
	"time"
)

type Cluster struct {
	opts options
}

type options struct {
	connectionTimeout time.Duration
	readTimeout       time.Duration
	writeTimeout      time.Duration

	logError func(ctx context.Context, err error)
}

// 通过一个选项为一个函数指针来达到一个目的：设置选项中数据的状态
// golang 函数指针的用法
type Option func(c *options)

// 设置某个参数的一个具体实现，用到了闭包的用法
// 不仅仅只是设置,采用闭包的目的是为了更为优化，更好用， 对用户更友好
func LogError(f func(ctx context.Context, err error)) Option {
	return func(opts *options) {
		opts.logError = f
	}
}

// 对于关键数据变量的赋值采用一个方法实现而不是直接设置
func ConnectionTimeout(d time.Duration) Option {
	return func(opts *options) {
		opts.connectionTimeout = d
	}
}

func ReadTime(d time.Duration) Option {
	return func(opts *options) {
		opts.readTimeout = d
	}
}

func WriteTimeout(d time.Duration) Option {
	return func(opts *options) {
		opts.writeTimeout = d
	}
}

// 构造行数的具体实现，传入一个 Option, new 一个对象并赋值
// 如果参数多， 也不需要传入很多的参数， 只需要传入 opts	 ...Option即可
func NewCluster(opts ...Option) *Cluster {
	clusterOpts := options{}
	for _, opt := range opts {
		// 函数指针的复制调用
		opt(&clusterOpts)
	}
	cluster := new(Cluster)
	cluster.opts = clusterOpts
	return cluster
}
